﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using SdmxMl.Helper;
using SdmxMl.Common;

namespace SdmxMl.GenericData
{
    /// <summary>
    /// ObsType defines the structure of an observation. This includes a time and 
    /// observation value, as well as values for each of the attributes assigned at 
    /// the observation level by the key family. In a delete message, only the time 
    /// need be given, indicating that the observation identified by the key and time 
    /// should be deleted. For an update message, both time and observation value are 
    /// required. If any attributes appear in a delete message, any valid value supplied 
    /// for an attribute indicates that the current value should be deleted.	
    /// </summary>
    public class ObsType
    {
        #region Properties

        private TimePeriodType _time;
        public TimePeriodType Time
        {
            get { return _time; }
            set { _time = value; }
        }

        /// <summary>Optional obs value </summary>
        private ValueType _obsValue;
        public ValueType ObsValue
        {
            get { return _obsValue; }
            set { _obsValue = value; }
        }

        private ValueListTag _attributes;
        public ValueTypeList Attributes
        {
            get { return _attributes.ValueList; }
        }

        /// <summary></summary>
        private AnnotationList annotationList;
        public AnnotationList AnnotationList
        {
            get { return annotationList; }
            set { annotationList = value; }
        }

        #endregion //Properties

        #region Construction

        private void Init()
        {
            Time = new TimePeriodType();
            AnnotationList = new AnnotationList();
        }

        public ObsType()
        {
            Init();
            _attributes = new ValueListTag("Attributes");
        }


        public ObsType(XmlNode nodeArtefact, XmlNamespaceManager nsmgr)
        {
            XmlNodeList nodeList = null;
            Init();

            // Time
            string stime = Xmlhelper.GetNodeText(nodeArtefact, "./generic:Time", nsmgr);
            if (stime.Length > 0)
                Time.UpdateInternal(stime);

            // Obs can be null
            XmlNode nodeObs = nodeArtefact.SelectSingleNode("./generic:ObsValue", nsmgr);
            if (nodeObs != null)
                _obsValue = new ValueType(nodeObs, nsmgr);

            // list attributes
            _attributes = new ValueListTag("Attributes", nodeArtefact, nsmgr);

            // Annotations
            nodeList = nodeArtefact.SelectNodes("./generic:Annotations/common:Annotation", nsmgr);
            foreach (XmlNode na in nodeList)
            {
                Annotation a = new Annotation(na, nsmgr);
                annotationList.Add(a);
            }
        }

        #endregion //Construction

        #region XML serialize
        public void WriteXml(XmlTextWriter xw, string prefix, string tag)
        {
            xw.WriteStartElement(prefix, tag, null);

            // Required
            xw.WriteElementString(prefix, "Time", null, Time.ToString());

            //Obs
            if (_obsValue != null)
                _obsValue.WriteXml(xw, prefix, "Value");

            // Reported Attributes 
            _attributes.WriteXml(xw);

            // Annotations
            AnnotationList.WriteXml(xw, prefix, null);

            xw.WriteEndElement();
        }


        #endregion //XML serialize

    }


    public class ObsTypeList : List<ObsType>
    {
    }
}
